#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#define NUM 1024
#define SIZE 64
#define SEP " "
 char cwd[1024];
 char enval[1024];
 int lastcode;
char*homepath()
{
    char *home = getenv("HOME");
    if(home) return home;
    else return (char*)".";
}

const char *getUsername()
{
    const char *name = getenv("USER");
    if(name) return name;
    else return "none";
}
const char *getHostname()
{
    const char *hostname = getenv("HOSTNAME");
    if(hostname) return hostname;
    else return "none";
}
const char *getCwd()
{
    const char *cwd = getenv("PWD");
    if(cwd) return cwd;
    else return "none";
}
int getUserCommand(char*command,int num)
{
    printf("[%s@%s %s]# ", getUsername(), getHostname(), getCwd());
    char*r=fgets(command,num,stdin);
    if(r==NULL) return -1;
    command[strlen(command)-1]='\0';
    return strlen(command);
}
void commandSplit(char*in,char*out[])
{
    int argc=0;
    out[argc++]=strtok(in,SEP);
    while(out[argc++]=strtok(NULL,SEP));
}
int evecute(char*argv[])
{

    pid_t id=fork();
    if(id<0) return -1;
    else if(id==0)
    {
        execvp(argv[0],argv);
        exit(1);
    }
    else{
        int status=0;
        pid_t rid=waitpid(id,&status,0);
        if(rid>0){lastcode=((status>>8)&0xff);}
    }
    return 0;
}
void cd(const char*path)
{
    chdir(path);
    char tmp[1024];
    getcwd(tmp,sizeof(cwd));
    sprintf(cwd,"PWD=%s",tmp);
    putenv(cwd);

}
int doBuildin(char*argv[])
{
    if(strcmp(argv[0],"cd")==0)
    {
        char*path=NULL;
        if(argv[1]==NULL) path=".";
        else path=argv[1];
        cd(path);
        return 1;
    }
    else if(strcmp(argv[0],"export")==0)
    {
        if(argv[1]==NULL) return 1;
        strcpy(enval,argv[1]);
        putenv(enval);
        return 1;
    }
    else if(strcmp(argv[0],"echo")==0)
    {
        if(argv[1]==NULL)
        {
            printf("\n");
            return 1;
        }
        char*val=argv[1]+1;
        if(strcmp(val,"?")==0)
        {
            printf("%d\n",lastcode);
            lastcode=0;
        }
        else{
            printf("%s\n",getenv(val));
        }
        return 1;
    }
    
    return 0;
}
int main()
{
    while(1)
    {
    char usercommand[NUM];
    char*argv[SIZE];
    int n=getUserCommand(usercommand,sizeof(usercommand));
    if(n<=0) continue;
    commandSplit(usercommand,argv);
    n=doBuildin(argv);
    if(n) continue;
    evecute(argv);
    }
    return 0;
}
